home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / fragrouter / Libnet-0.99b / src / bpf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-26  |  6.3 KB  |  272 lines

  1. /*
  2.  *  $Id: bpf.c,v 1.1.1.1 1999/05/18 15:33:42 dugsong Exp $
  3.  *
  4.  *  libnet
  5.  *  bpf.c - low-level bpf routines
  6.  *
  7.  *  Copyright (c) 1998, 1999 Mike D. Schiffman <mike@infonexus.com>
  8.  *                           route|daemon9 <route@infonexus.com>
  9.  *  All rights reserved.
  10.  *
  11.  * Copyright (c) 1993, 1994, 1995, 1996, 1998
  12.  *    The Regents of the University of California.  All rights reserved.
  13.  *
  14.  * Redistribution and use in source and binary forms, with or without
  15.  * modification, are permitted provided that: (1) source code distributions
  16.  * retain the above copyright notice and this paragraph in its entirety, (2)
  17.  * distributions including binary code include the above copyright notice and
  18.  * this paragraph in its entirety in the documentation or other materials
  19.  * provided with the distribution, and (3) all advertising materials mentioning
  20.  * features or use of this software display the following acknowledgement:
  21.  * ``This product includes software developed by the University of California,
  22.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  23.  * the University nor the names of its contributors may be used to endorse
  24.  * or promote products derived from this software without specific prior
  25.  * written permission.
  26.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  27.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  28.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  29.  */
  30.  
  31. #include <sys/param.h>  /* optionally get BSD define */
  32. #include <sys/timeb.h>
  33. #include <sys/file.h>
  34. #include <sys/ioctl.h>
  35.  
  36. #if (HAVE_CONFIG_H)
  37. #include "../include/config.h"
  38. #endif 
  39. #include "../include/libnet.h"
  40. #include <sys/sysctl.h>
  41. #include <net/route.h>
  42. #include <net/if_dl.h>
  43. #include "../include/gnuc.h"
  44. #include "../include/bpf.h"
  45.  
  46. #ifdef HAVE_OS_PROTO_H
  47. #include "../include/os-proto.h"
  48. #endif
  49.  
  50. int
  51. bpf_open(char *errbuf)
  52. {
  53.     int i, fd;
  54.     char device[sizeof "/dev/bpf000"];
  55.  
  56.     /*
  57.      *  Go through all the minors and find one that isn't in use.
  58.      */
  59.     for (i = 0;;i++)
  60.     {
  61.         sprintf(device, "/dev/bpf%d", i);
  62.  
  63.         fd = open(device, O_RDWR);
  64.         if (fd == -1 && errno == EBUSY)
  65.         {
  66.             /*
  67.              *  Device is busy.
  68.              */
  69.             continue;
  70.         }
  71.         else
  72.         {
  73.             /*
  74.              *  Either we've got a valid file descriptor, or errno is not
  75.              *  EBUSY meaning we've probably run out of devices.
  76.              */
  77.             break;
  78.         }
  79.     }
  80.  
  81.     if (fd == -1)
  82.     {
  83.         sprintf(errbuf, "%s: %s", device, ll_strerror(errno));
  84.     }
  85.     return (fd);
  86. }
  87.  
  88.  
  89. struct link_int *
  90. open_link_interface(char *device, char *ebuf)
  91. {
  92.     struct ifreq ifr;
  93.     struct bpf_version bv;
  94.     u_int v;
  95.     struct link_int *l;
  96.  
  97.     l = (struct link_int *)malloc(sizeof(*l));
  98.     if (!l)
  99.     {
  100.         sprintf(ebuf, "malloc: %s", ll_strerror(errno));
  101. #if (__DEBUG)
  102.         fprintf(stderr, "low_level-bpf malloc %s", ll_strerror(errno));
  103. #endif
  104.         return (NULL);
  105.     }
  106.  
  107.     memset(l, 0, sizeof(*l));
  108.  
  109.     l->fd = bpf_open(ebuf);
  110.     if (l->fd == -1)
  111.     {
  112.         goto bad;
  113.     }
  114.  
  115.     /*
  116.      *  Get bpf version.
  117.      */
  118.     if (ioctl(l->fd, BIOCVERSION, (caddr_t)&bv) < 0)
  119.     {
  120.         sprintf(ebuf, "BIOCVERSION: %s", ll_strerror(errno));
  121.         goto bad;
  122.     }
  123.  
  124.     if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION)
  125.     {
  126.         sprintf(ebuf, "kernel bpf filter out of date");
  127.         goto bad;
  128.     }
  129.  
  130.     /*
  131.      *  Attach network interface to bpf device.
  132.      */
  133.     strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
  134.     if (ioctl(l->fd, BIOCSETIF, (caddr_t)&ifr) == -1)
  135.     {
  136.         sprintf(ebuf, "%s: %s", device, ll_strerror(errno));
  137.         goto bad;
  138.     }
  139.  
  140.     /*
  141.      *  Get the data link layer type.
  142.      */
  143.     if (ioctl(l->fd, BIOCGDLT, (caddr_t)&v) == -1)
  144.     {
  145.         sprintf(ebuf, "BIOCGDLT: %s", ll_strerror(errno));
  146.         goto bad;
  147.     }
  148.  
  149.     /*
  150.      *  Assign link type and offset.
  151.      */
  152.     switch (v)
  153.     {
  154.         case DLT_SLIP:
  155.             l->linkoffset = 0x10;
  156.             break;
  157.         case DLT_RAW:
  158.             l->linkoffset = 0x0;
  159.             break;
  160.         case DLT_PPP:
  161.             l->linkoffset = 0x04;
  162.             break;
  163.         case DLT_EN10MB:
  164.         default:
  165.             l->linkoffset = 0xe;     /* default to ethernet */
  166.             break;
  167.     }
  168. #if _BSDI_VERSION - 0 >= 199510
  169.     switch (v)
  170.     {
  171.         case DLT_SLIP:
  172.             v = DLT_SLIP_BSDOS;
  173.             l->linkoffset = 0x10;
  174.             break;
  175.         case DLT_PPP:
  176.             v = DLT_PPP_BSDOS;
  177.             l->linkoffset = 0x04;
  178.             break;
  179.     }
  180. #endif
  181.     l->linktype = v;
  182.  
  183.     return (l);
  184.  
  185. bad:
  186.     close(l->fd);      /* this can fail ok */
  187.     free(l);
  188.     return (NULL);
  189. }
  190.  
  191.  
  192. int
  193. close_link_interface(struct link_int *l)
  194. {
  195.     return (close(l->fd));
  196. }
  197.  
  198.  
  199. int
  200. write_link_layer(struct link_int *l, const u_char *device, u_char *buf, int len)
  201. {
  202.     int c;
  203.  
  204.     c = write(l->fd, buf, len);
  205.     if (c != len)
  206.     {
  207. #if (__DEBUG)
  208.         fprintf(stderr, "write_link_layer: %d bytes written (%s)\n", c,
  209.             strerror(errno));
  210. #endif
  211.     }
  212.     return (c);
  213. }
  214.  
  215.  
  216. struct ether_addr *
  217. get_hwaddr(struct link_int *l, const u_char *device, char *ebuf)
  218. {
  219.     int mib[6];
  220.     size_t len;
  221.     char *buf, *next, *end;
  222.     struct if_msghdr *ifm;
  223.     struct sockaddr_dl *sdl;
  224.     struct ether_addr *ea = NULL;
  225.  
  226.     mib[0] = CTL_NET;
  227.     mib[1] = AF_ROUTE;
  228.     mib[2] = 0;
  229.     mib[3] = AF_LINK;
  230.     mib[4] = NET_RT_IFLIST;
  231.     mib[5] = 0;
  232.  
  233.     if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
  234.     {
  235.         return (NULL);
  236.     }
  237.  
  238.     if (!(buf = (char *)malloc(len)))
  239.     {
  240.         return NULL;
  241.     }
  242.    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
  243.    {
  244.         free(buf);
  245.         return (NULL);
  246.     }
  247.     end = buf + len;
  248.  
  249.     for (next = buf ; next < end ; next += ifm->ifm_msglen)
  250.     {
  251.         ifm = (struct if_msghdr *)next;
  252.         if (ifm->ifm_type == RTM_IFINFO)
  253.         {
  254.             sdl = (struct sockaddr_dl *)(ifm + 1);
  255.             if (strncmp(&sdl->sdl_data[0], device, sdl->sdl_nlen) == 0)
  256.             {
  257.                 if (!(ea = malloc(sizeof(struct ether_addr))))
  258.                 {
  259.                     return (NULL);
  260.                 }
  261.                 memcpy(ea->ether_addr_octet, LLADDR(sdl), ETHER_ADDR_LEN);
  262.                 break;
  263.             }
  264.         }
  265.     }
  266.     free(buf);
  267.     return (ea);
  268. }
  269.  
  270.  
  271. /* EOF */
  272.